package com.trip.wechat.platform.subsystem.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.trip.wechat.platform.model.user.UserInfoBO;
import com.trip.wechat.platform.model.user.UserListResultBO;
import com.trip.wechat.platform.subsystem.UserInfoFacade;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.StringJoiner;

/**
 * 功能说明: <br>
 * 系统说明: <br>
 * 模块说明: <br>
 * 功能描述: <br>
 */
@Component("mp.userInfo")
public class UserInfoFacadeMPImpl implements UserInfoFacade {

    final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Value("${mp.user_list.url:https://api.weixin.qq.com/cgi-bin/user/get}")
    protected String usersListUrl;
    @Value("${mp.user_info.url:https://api.weixin.qq.com/cgi-bin/user/info}")
    protected String userInfoUrl;

    @Autowired
    OkHttpClient httpClient;

    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public UserListResultBO fetchUserList(String accessToken, String nextOpenId) {
        if (Strings.isNullOrEmpty(accessToken)) {
            LOGGER.warn("[mp.userInfo.fetchUserList] accessToken cannot be empty!");
            //return createUserListErrorInfo(CodeDict.C_SERVICE_FAIL, "accessToken is empty");
            return null;
        }

        StringJoiner joiner = new StringJoiner("&", "?", "");

        joiner.add(Joiner.on("=").join("access_token", accessToken));
        if (!Strings.isNullOrEmpty(nextOpenId)) {
            joiner.add(Joiner.on("=").join("next_openid", nextOpenId));
        }
        try {
            Request request = new Request.Builder()
                    .url(usersListUrl + joiner.toString())
                    .get()
                    .build();
            Response response = httpClient.newCall(request).execute();

            String responseBody = response.body().string();

            return objectMapper.readValue(responseBody, UserListResultBO.class);
        } catch (IOException e) {
            LOGGER.warn("[mp.userInfo.fetchUserList] failed! IOException! {}", e.getMessage());
            //return createUserListErrorInfo(CodeDict.C_SERVICE_FAIL, "fetch failed! IOException");
            return null;
        } catch (Exception e) {
            LOGGER.warn("[mp.userInfo.fetchUserList] failed! {}! {}", e.getClass().getName(), e.getMessage());
            // return createUserListErrorInfo(CodeDict.C_SERVICE_FAIL, "fetch failed!");
            return null;
        }
    }

    @Override
    public UserInfoBO fetchUserInfo(String accessToken, String openid) {
        if (Strings.isNullOrEmpty(accessToken) || Strings.isNullOrEmpty(openid)) {
            LOGGER.warn("[mp.userInfo.fetchUserInfo] accessToken or openid cannot be empty!");
            //return createUserInfoErrorInfo(CodeDict.C_SERVICE_FAIL, "accessToken or openid is empty");
            return null;
        }

        StringJoiner joiner = new StringJoiner("&", "?", "");
        joiner.add(Joiner.on("=").join("access_token", accessToken));
        joiner.add(Joiner.on("=").join("openid", openid));
        joiner.add(Joiner.on("=").join("lang", "zh_CN"));

        try {

            Request request = new Request.Builder()
                    .url(userInfoUrl + joiner.toString())
                    .get()
                    .build();
            Response response = httpClient.newCall(request).execute();

            String responseBody = response.body().string();

            return objectMapper.readValue(responseBody, UserInfoBO.class);
        } catch (IOException e) {
            LOGGER.warn("[mp.userInfo.fetchUserInfo] failed! IOException! {}", e.getMessage());
//            return createUserInfoErrorInfo(CodeDict.C_SERVICE_FAIL, "fetch failed! IOException");
            return null;
        } catch (Exception e) {
            LOGGER.warn("[mp.userInfo.fetchUserInfo] failed! {}! {}", e.getClass().getName(), e.getMessage());
//            return createUserInfoErrorInfo(CodeDict.C_SERVICE_FAIL, "fetch failed!");
            return null;
        }
    }

    protected UserListResultBO createUserListErrorInfo(int code, String message) {
        UserListResultBO bo = new UserListResultBO();
        bo.setErrcode(code);
        bo.setErrmsg(message);
        return bo;
    }

    protected UserInfoBO createUserInfoErrorInfo(int code, String message) {
        UserInfoBO bo = new UserInfoBO();
        bo.setErrcode(code);
        bo.setErrmsg(message);
        return bo;
    }
}
